package manager.player;


import java.sql.SQLException;
import java.util.ArrayList;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.ObjectUtils.Null;
import org.springframework.beans.BeansException;


import com.fasterxml.jackson.core.JsonProcessingException;

import database.DBService;
import database.PlayerSingerDBServer;
import database.PlayerSongDBServer;
import database.SingleSongScoreDBServer;
import database.SongBaseDBService;
import database.pojo.PlayerCollectSingerInfo;
import database.pojo.PlayerCollectSongInfo;
import database.pojo.PlayerHistorySongInfo;
import database.pojo.SingleSongScoreInfo;
import database.pojo.UserInfo;
import io.netty.channel.ChannelFuture;
import manager.connection.ClientConnectionManager;
import manager.pay.HandleNotify;
import manager.player.basic.state.GeneralPlayerState;
import manager.player.basic.type.BasicPlayerInfo;
import manager.player.basic.type.GeneralPlayerInfo;
import manager.player.basic.type.SingerInfo;
import manager.player.basic.type.SongInfo;
import manager.player.basic.type.songRankInfo;
import manager.rank.InsertToRedis;
import manager.rank.QuireRankOfSong;
import net.socket.server.protocal.PROTOID;
import net.socket.server.request.CancelCollectSingerRequest;
import net.socket.server.request.CancelCollectSongRequest;
import net.socket.server.request.CollectSingerRequest;
import net.socket.server.request.CollectSongRequest;
import net.socket.server.request.GetCollectInfoRequest;
import net.socket.server.request.GetHistorySongListRequest;
import net.socket.server.request.IRequest;
import net.socket.server.request.LocalPlayResultRequest;
import net.socket.server.response.CancelCollectSingerResponse;
import net.socket.server.response.CancelCollectSongResponse;
import net.socket.server.response.CollectSingerResponse;
import net.socket.server.response.CollectSongResponse;
import net.socket.server.response.GetCollectSingerInfoResponse;
import net.socket.server.response.GetCollectSongInfoResponse;
import net.socket.server.response.GetHistorySongListResponse;
import net.socket.server.response.LocalPlayResultResponse;
import observable.subject.MessageCenter;
import redis.clients.jedis.Jedis;
import util.MyFactory;
import util.RedisUtil;
import util.ResultTypeList;

public class PlayerManager {
	// openid of the user, and the player's info
	private  static Map<String, GeneralPlayerInfo> playerList = new HashMap<String, GeneralPlayerInfo>();
	
	
	
	private ClientConnectionManager ccm = null;
	private Jedis myJedis =null;
	
	
	
	public void init() {
		
		
		MessageCenter mc = MyFactory.context.getBean("MessageCenter", MessageCenter.class);
		mc.register(PROTOID.COLLECT_SONG_REQ, (int cmd, IRequest request)->collectSong(cmd, request));
		mc.register(PROTOID.COLLECT_SINGER_REQ, (int cmd, IRequest request)->collectSinger(cmd, request));
		mc.register(PROTOID.LOCAL_PLAY_RESULT_REQ, (int cmd, IRequest request)->localPlayResult(cmd, request));
		mc.register(PROTOID.GET_HISTORY_SONG_LIST_REQ, (int cmd, IRequest request)->getHistorySongList(cmd, request));
		mc.register(PROTOID.GET_COLLECT_INFO_REQ, (int cmd, IRequest request)->getCollectInfo(cmd, request));
		mc.register(PROTOID.CANCEL_COLLECT_SONG_REQ, (int cmd, IRequest request)->CancelCollectSong(cmd, request));
		mc.register(PROTOID.CANCEL_COLLECT_SINGER_REQ, (int cmd, IRequest request)->CancelCollectSinger(cmd, request));
		
		ccm = MyFactory.context.getBean("ClientConnectionManager", ClientConnectionManager.class);
		
	}
	private int CancelCollectSinger(int cmd, IRequest request) throws  IllegalArgumentException, IllegalAccessException, JsonProcessingException {
		
		CancelCollectSingerRequest req =(CancelCollectSingerRequest)request;
		CancelCollectSingerResponse rsp = new CancelCollectSingerResponse();
		if("".equals(req.getOpenId())||"".equals(req.getSingerId())) {
			rsp.setResult(ResultTypeList.NULL_ARGS);
			ccm.sendResponse(PROTOID.CANCEL_COLLECT_SINGER_RSP, req.getMachineId(), rsp);
			return ResultTypeList.NULL_ARGS;
		}
		ChannelFuture cf = null;
		
		try {
			MyFactory.context.getBean("PlayerSingerDBServer", PlayerSingerDBServer.class).delect(req.getOpenId(), req.getSingerId());
			rsp.setResult(ResultTypeList.SUCCESS);
		} catch (BeansException | SQLException e) {
			rsp.setResult(ResultTypeList.DELECT_DB_EXCEPTION);
			e.printStackTrace();
		}
		cf = ccm.sendResponse(PROTOID.CANCEL_COLLECT_SINGER_RSP, req.getMachineId(), rsp);
		if(cf == null) {
			return ResultTypeList.NO_CONNECTION_FOUND;
		}else {
			return ResultTypeList.SUCCESS;
		}
	}
	private int CancelCollectSong(int cmd, IRequest request) throws  IllegalArgumentException, IllegalAccessException, JsonProcessingException {
		CancelCollectSongRequest req = (CancelCollectSongRequest)request;
		CancelCollectSongResponse rsp = new CancelCollectSongResponse();
		if("".equals(req.getOpenId())||"".equals(req.getSongId())) {
			rsp.setResult(ResultTypeList.NULL_ARGS);
			ccm.sendResponse(PROTOID.CANCEL_COLLECT_SONG_RSP, req.getMachineId(), rsp);
			return ResultTypeList.NULL_ARGS;
		}
		ChannelFuture cf = null;
		try {
			MyFactory.context.getBean("PlayerSongDBServer",PlayerSongDBServer.class).delect(req.getOpenId(), req.getSongId());
			rsp.setResult(ResultTypeList.SUCCESS);
		} catch (BeansException | SQLException e) {
			e.printStackTrace();
			rsp.setResult(ResultTypeList.DELECT_DB_EXCEPTION);
		}
		cf = ccm.sendResponse(PROTOID.CANCEL_COLLECT_SONG_RSP, req.getMachineId(), rsp);
		
		if(cf == null) {
			return ResultTypeList.NO_CONNECTION_FOUND;
		}else {
			return ResultTypeList.SUCCESS;
		}
	}
	
	private int getCollectInfo(int cmd, IRequest request) throws BeansException, SQLException, IllegalArgumentException, IllegalAccessException, JsonProcessingException {
		GetCollectInfoRequest req = (GetCollectInfoRequest)request;
		ChannelFuture cf = null;
		if (req.getCollectType() ==0) {
			GetCollectSingerInfoResponse rsp = new GetCollectSingerInfoResponse();
			if("".equals(req.getOpenId())) {
				rsp.setResult(ResultTypeList.NULL_ARGS);
				ccm.sendResponse(PROTOID.GET_COLLECT_INFO_RSP, req.getMachineId(), rsp);
				return ResultTypeList.NULL_ARGS;
			}
			List<PlayerCollectSingerInfo> PCSInfoList = null;
			List<SingerInfo> singerInfoList = new ArrayList<SingerInfo>();
			SingerInfo singerInfo = null;
			PCSInfoList = MyFactory.context.getBean("PlayerSingerDBServer", PlayerSingerDBServer.class).selectPlayerCollectSingerInfoByOpenId(req.getOpenId());
	 		rsp.setSingerNum(PCSInfoList.size());
	 		for(PlayerCollectSingerInfo pCistorySongInfo:PCSInfoList) {
	 			singerInfo = new SingerInfo();
	 			singerInfo.setSingerId(pCistorySongInfo.getSingerId());
	 			singerInfo.setSingTimes(pCistorySongInfo.getSingTimes());
	 			singerInfoList.add(singerInfo);		
	 		}
	 		rsp.setResult(ResultTypeList.SUCCESS);
	 		rsp.setsingerList(singerInfoList);
	 		cf = ccm.sendResponse(PROTOID.GET_COLLECT_INFO_RSP, req.getMachineId(), rsp);
			if(cf == null) {
				return ResultTypeList.NO_CONNECTION_FOUND;
			}else {
				return ResultTypeList.SUCCESS;
			}
			
		}else {
			GetCollectSongInfoResponse rsp = new GetCollectSongInfoResponse();
			if("".equals(req.getOpenId())) {
				rsp.setResult(ResultTypeList.NULL_ARGS);
				ccm.sendResponse(PROTOID.GET_COLLECT_INFO_RSP, req.getMachineId(), rsp);
				return ResultTypeList.NULL_ARGS;
			}
			List<PlayerCollectSongInfo> PCSInfoList = null;
			List<SongInfo> songInfoList = new ArrayList<SongInfo>();
			SongInfo songInfo = null;
			PCSInfoList = MyFactory.context.getBean("PlayerSongDBServer", PlayerSongDBServer.class).selectPlayerCollectSongInfoByOpenId(req.getOpenId());
	 		rsp.setSongNum(PCSInfoList.size());
	 		for(PlayerCollectSongInfo pCollectSongInfo:PCSInfoList) {
	 			songInfo = new SongInfo();
	 			songInfo.setSongId(pCollectSongInfo.getSongId());
	 			songInfo.setMaxScore(-1);//现在默认传0，以后看需求加
	 			songInfo.setRank(-1);//现在默认传0，以后看需求加
	 			songInfoList.add(songInfo);		
	 		}
	 		rsp.setResult(ResultTypeList.SUCCESS);
	 		rsp.setSongList(songInfoList);
	 		cf = ccm.sendResponse(PROTOID.GET_COLLECT_INFO_RSP, req.getMachineId(), rsp);
			if(cf == null) {
				return ResultTypeList.NO_CONNECTION_FOUND;
			}else {
				return ResultTypeList.SUCCESS;
			}
		}
		
	}

	private int getHistorySongList(int cmd, IRequest request) throws  IllegalArgumentException, IllegalAccessException, JsonProcessingException {
		GetHistorySongListRequest req = (GetHistorySongListRequest)request;
		GetHistorySongListResponse rsp = new GetHistorySongListResponse();
		ChannelFuture cf = null;
		if("".equals(req.getOpenId())) {
			rsp.setResult(ResultTypeList.NULL_ARGS);
			ccm.sendResponse(PROTOID.GET_HISTORY_SONG_LIST_RSP, req.getMachineId(), rsp);
			return ResultTypeList.NULL_ARGS;
		}
		//List<PlayerHistorySongInfo> PHSInfoList = null;
		Set<String> songSet = MyFactory.context.getBean("QuireRankOfSong", QuireRankOfSong.class).getSongIdSet(req.getOpenId());
		List<SongInfo> songInfoList = new ArrayList<SongInfo>();
		SongInfo songInfo = null;
		for(String songId: songSet) {
			songInfo = new SongInfo();
			songInfo.setSongId(songId);
			songInfo.setMaxScore(MyFactory.context.getBean("QuireRankOfSong", QuireRankOfSong.class).getSongScoreOfOpenId(songId, req.getOpenId()));
			songInfo.setRank(MyFactory.context.getBean("QuireRankOfSong", QuireRankOfSong.class).getSongRankOfOpenId(songId, req.getOpenId()));
			songInfoList.add(songInfo);
		}
 		rsp.setSongNum(songSet.size());
		rsp.setResult(ResultTypeList.SUCCESS);
 		rsp.setSongList(songInfoList);
 		cf = ccm.sendResponse(PROTOID.GET_HISTORY_SONG_LIST_RSP, req.getMachineId(), rsp);
		if(cf == null) {
			return ResultTypeList.NO_CONNECTION_FOUND;
		}else {
			return ResultTypeList.SUCCESS;
		}
	}

	private int localPlayResult(int cmd, IRequest request) throws BeansException, SQLException, IllegalArgumentException, IllegalAccessException, JsonProcessingException {
		LocalPlayResultRequest req = (LocalPlayResultRequest)request;
		LocalPlayResultResponse rsp = new LocalPlayResultResponse();
		if("".equals(req.getOpenId())||"".equals(req.getSongId())) {
			rsp.setResult(ResultTypeList.NULL_ARGS);
			ccm.sendResponse(PROTOID.LOCAL_PLAY_RESULT_RSP, req.getMachineId(), rsp);
			return ResultTypeList.NULL_ARGS;
		}
		PlayerHistorySongInfo PHSInfo = new PlayerHistorySongInfo();
		ChannelFuture cf = null;
		PHSInfo.setOpenId(req.getOpenId());
		PHSInfo.setSongId(req.getSongId());
		int[] ranks =new int[2];
		/*
		//ArrayList<Integer> scoreList =null;
		SingleSongScoreInfo sssInfo = new SingleSongScoreInfo();
		int score = req.getScore();
		
		sssInfo.setOpenId(req.getOpenId());
		sssInfo.setRank(rank);
		sssInfo.setSongId(req.getSongId());
		sssInfo.setScore(score);
		sssInfo.setMachineId(req.getMachineId());*/
		
		ranks = MyFactory.context.getBean("InsertToRedis",InsertToRedis.class).insertRedisSongRankAndReturnThisRank(req);
		rsp.setTheRank(ranks[1]);//本机排名
		rsp.setMaxRank(ranks[0]);//全国排名
		/*int maxScore = getTheMaxScoreofSingleSongScoreRank(req.getOpenId(),req.getSongId());
		//System.out.println("getTheMaxScoreofSingleSongScoreRank: "+ maxScore);
		maxRank =getRankOfThePeopleFromSingleSongScoreRank(req.getSongId(),req.getOpenId());
		*/
		//rsp.setMaxRank(maxRank);
		//System.out.println("selectRank--"+rsp.getMaxRank());
		
		rsp.setResult(ResultTypeList.SUCCESS);
		cf = ccm.sendResponse(PROTOID.LOCAL_PLAY_RESULT_RSP, req.getMachineId(), rsp);
		MyFactory.context.getBean("SongBaseDBService", SongBaseDBService.class).updateSingTimes(req.getOpenId());
		if(cf == null) {
			return ResultTypeList.NO_CONNECTION_FOUND;
		}else {
			return ResultTypeList.SUCCESS;
		}
	}

	private int getRankOfThePeopleFromSingleSongScoreRank(String songId, String openId) {
		int maxRank =0;
		try {
			myJedis=MyFactory.context.getBean("RedisUtil", RedisUtil.class).getJedis();
			maxRank =myJedis.zrevrank("vod:SingleSongScoreRank:"+songId, openId).intValue()+1;
		}catch (Exception e) {
			System.out.println("insertRedis get a Exception---"+e);
			return maxRank;
		}finally {
			if(null != myJedis)
				myJedis.close(); // 释放资源还给连接池	
		}
		return maxRank;
	}
	private int getTheMaxScoreofSingleSongScoreRank(String openId, String songId) {
		int maxScore =0;
		try {
			myJedis=MyFactory.context.getBean("RedisUtil", RedisUtil.class).getJedis();
			maxScore =(int)Math.pow(myJedis.zscore("vod:SingleSongScoreRank:"+songId, openId), 1);
		}catch (Exception e) {
			System.out.println("insertRedis get a Exception---"+e);
			return maxScore;
		}finally {
			if(null != myJedis)
				myJedis.close(); // 释放资源还给连接池		
		}
		return maxScore;
	}
	
	private int collectSinger(int cmd, IRequest request) throws BeansException, SQLException, IllegalArgumentException, IllegalAccessException, JsonProcessingException {
		
		CollectSingerRequest req = (CollectSingerRequest)request;
		CollectSingerResponse rsp = new CollectSingerResponse();
		if("".equals(req.getOpenId())||"".equals(req.getSingerId())) {
			rsp.setResult(ResultTypeList.NULL_ARGS);
			ccm.sendResponse(PROTOID.COLLECT_SINGER_RSP, req.getMachineId(), rsp);
			return ResultTypeList.NULL_ARGS;
		}
		PlayerCollectSingerInfo PCSInfo = new PlayerCollectSingerInfo();
		ChannelFuture cf = null;
		PCSInfo.setOpenId(req.getOpenId());
		PCSInfo.setSingerId(req.getSingerId());
		boolean scc = MyFactory.context.getBean("PlayerSingerDBServer", PlayerSingerDBServer.class).insertPlayerCollectSingerInfo(PCSInfo);
		if(!scc) {
			rsp.setResult(ResultTypeList.INSERT_DB_EXCEPTION);
		}else {
			rsp.setResult(ResultTypeList.SUCCESS);
		}
		cf = ccm.sendResponse(PROTOID.COLLECT_SINGER_RSP, req.getMachineId(), rsp);
		if(cf == null) {
			return ResultTypeList.NO_CONNECTION_FOUND;
		}else {
			return ResultTypeList.SUCCESS;
		}
	}

	private int collectSong(int cmd, IRequest request) throws BeansException, SQLException, IllegalArgumentException, IllegalAccessException, JsonProcessingException {
		CollectSongRequest req = (CollectSongRequest)request;
		CollectSongResponse rsp = new CollectSongResponse();
		if("".equals(req.getOpenId())||"".equals(req.getSongId())) {
			rsp.setResult(ResultTypeList.NULL_ARGS);
			ccm.sendResponse(PROTOID.COLLECT_SONG_RSP, req.getMachineId(), rsp);
			return ResultTypeList.NULL_ARGS;
		}
		PlayerCollectSongInfo PCSInfo = new PlayerCollectSongInfo();
		ChannelFuture cf = null;
		PCSInfo.setOpenId(req.getOpenId());
		PCSInfo.setSongId(req.getSongId());
		//System.out.println("collectSong---"+PCSInfo.getSongId());
		boolean scc =MyFactory.context.getBean("PlayerSongDBServer", PlayerSongDBServer.class).insertPlayerCollectSong(PCSInfo);
		if(!scc) {
			rsp.setResult(ResultTypeList.INSERT_DB_EXCEPTION);
		}else {
			rsp.setResult(ResultTypeList.SUCCESS);
		}
		cf = ccm.sendResponse(PROTOID.COLLECT_SONG_RSP, req.getMachineId(), rsp);
		if(cf == null) {
			return ResultTypeList.NO_CONNECTION_FOUND;
		}else {
			return ResultTypeList.SUCCESS;
		}
	}

	public BasicPlayerInfo getBasicPlayerInfo(String openId) throws BeansException, SQLException{
		GeneralPlayerInfo gPlayerInfo = playerList.get(openId);
		BasicPlayerInfo basicPlayerInfo = null;
		if(gPlayerInfo == null){
			UserInfo userinfo = MyFactory.context.getBean("DBService", DBService.class).selectUserInfoByOpenId(openId);
			basicPlayerInfo = new BasicPlayerInfo();
			if(userinfo.getHeadImgUrl() != null){
				basicPlayerInfo.setHeadImgURL(userinfo.getHeadImgUrl());
			}
			basicPlayerInfo.setNickName(userinfo.getNickName());
			basicPlayerInfo.setOpenId(userinfo.getWechatOpenid());
			basicPlayerInfo.setSex(userinfo.getSex());
			basicPlayerInfo.setAvatarId(userinfo.getAvatarId());
			basicPlayerInfo.setVipGrade(userinfo.getVipGrade());
			gPlayerInfo = new GeneralPlayerInfo();
			gPlayerInfo.setPlayerInfo(basicPlayerInfo);
			playerList.put(openId, gPlayerInfo);
		}
		else {
			basicPlayerInfo = gPlayerInfo.getPlayerInfo();
		}
		return basicPlayerInfo;
	}
	/*
	 * 通过openid查询选手的state
	 */
	public static int selectPlayerState(String openId) {
		GeneralPlayerInfo gPlayerInfo = playerList.get(openId);
		int state = GeneralPlayerState.CREATED;//默认状态
		if(gPlayerInfo != null) {
			state = gPlayerInfo.getState();
		}else {
			//System.out.println("selectPlayerState---selectPlayerState IS NULL");
		}
		return state;
	}
	public static void addPlayerFromList(String openId,GeneralPlayerInfo generalPlayerInfo) {
		synchronized (playerList) {
			playerList.put(openId, generalPlayerInfo);
		}
		
		
	}
	public static void  removePlayerFromList(String openId) {
		synchronized (playerList) {
			playerList.remove(openId);
		}
		
	}
	
	public boolean setPlayerState(String openId, int state){
		GeneralPlayerInfo gPlayerInfo = playerList.get(openId);
		if(gPlayerInfo == null)
			return false;
		else{
			gPlayerInfo.setState(state);
			return true;
		}
	}
	
	public GeneralPlayerInfo getGeneralPlayerInfo(String openId){
		return playerList.get(openId);
	}
	
	public boolean setPlayerSongId(String openId, String songId){
		GeneralPlayerInfo gPlayerInfo = playerList.get(openId);
		if(gPlayerInfo == null)
			return false;
		else{
			gPlayerInfo.setSongId(songId);
			return true;
		}
	}
	
	public boolean setPlayerMatchId(String openId, int matchId){
		GeneralPlayerInfo gPlayerInfo = playerList.get(openId);
		if(gPlayerInfo == null)
			return false;
		else{
			gPlayerInfo.setMatchId(matchId);
			return true;
		}
	}
	
	public boolean setPlayerAvatarId(String openId,int avatarId) {
		GeneralPlayerInfo gPlayerInfo = playerList.get(openId);
		if(gPlayerInfo == null)
			return false;
		else{
			gPlayerInfo.getPlayerInfo().setAvatarId(avatarId);
			return true;
		}
	}
	
	public boolean setPlayerVipGrader(String openId,int vipGrader) {
		GeneralPlayerInfo gPlayerInfo = playerList.get(openId);
		if(gPlayerInfo == null)
			return false;
		else{
			gPlayerInfo.getPlayerInfo().setVipGrade(vipGrader);
			return true;
		}
	}
}
